package br.ufrj.xml.model.persistence.dao.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;

import br.ufrj.xml.model.persistence.dao.ColumnDAO;
import br.ufrj.xml.model.persistence.dao.DAOFactory;
import br.ufrj.xml.model.persistence.dao.DataAccessException;
import br.ufrj.xml.model.persistence.dao.DocumentDAO;
import br.ufrj.xml.model.persistence.dao.GenericDAO;
import br.ufrj.xml.model.persistence.dao.RelationshipDAO;
import br.ufrj.xml.model.persistence.dao.SchemaDAO;
import br.ufrj.xml.model.persistence.dao.TableDAO;
import br.ufrj.xml.model.persistence.entity.ColumnVO;
import br.ufrj.xml.model.persistence.entity.DocumentVO;
import br.ufrj.xml.model.persistence.entity.RelationshipVO;
import br.ufrj.xml.model.persistence.entity.SchemaVO;
import br.ufrj.xml.model.persistence.entity.TableVO;
import br.ufrj.xml.util.MyConnection;

public class JdbcDAOFactory extends DAOFactory {
 
  private final ThreadLocal<Connection> threadConnection = new ThreadLocal<Connection>();
 
  public JdbcDAOFactory() {
    try {
      Class.forName(MyConnection.DRIVER);
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
  }

  @Override
  public DocumentDAO getDocumentDAO() {
	  return new DocumentJdbcDAO(getConnection());
  }

  @SuppressWarnings("unchecked")
  @Override
  public <T> GenericDAO<T, ?> getDao(Class<T> clazz) {
    if(clazz.equals(SchemaVO.class)) {
      return (GenericDAO<T, ?>) new SchemaJdbcDAO(getConnection());
    }else if(clazz.equals(DocumentVO.class)) {
      return (GenericDAO<T, ?>) new DocumentJdbcDAO(getConnection());
    }else if(clazz.equals(TableVO.class)) {
      return (GenericDAO<T, ?>) new TableJdbcDAO(getConnection());
    }else if(clazz.equals(ColumnVO.class)) {
      return (GenericDAO<T, ?>) new ColumnJdbcDAO(getConnection());
    }else if(clazz.equals(RelationshipVO.class)) {
      return (GenericDAO<T, ?>) new RelationshipJdbcDAO(getConnection());
    }       
    return null;
  }
 
  @Override
  public void closeConnection() {
    Connection current = threadConnection.get();
    try {
      if(current != null && !current.isClosed()) {
        current.close();
        threadConnection.set(null);
      }
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
  }
 
  @Override
  public void beginTransaction() {
    try {
      Connection current = getConnection();
      current.setAutoCommit(false);
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
  }
 
  @Override
  public void beginTransaction(int transactionIsolation) {
    try {
      Connection current = getConnection();
      current.setAutoCommit(false);
      current.setTransactionIsolation(transactionIsolation);
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
  }
 
  @Override
  public void commitTransaction() {
    try {
      Connection current = getConnection();
      current.commit();
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
  }
 
  @Override
  public void rollbackTransaction() {
    try {
      Connection current = getConnection();
      current.rollback();
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
  }

  private Connection getConnection() {
	  Connection current = super.myConnect;
    //Connection current = threadConnection.get();
    try {
      if(current == null || current.isClosed()) {
        current = DriverManager.getConnection( MyConnection.URL , MyConnection.USERNAME, MyConnection.SENHA );
        threadConnection.set(current);
      }
    } catch(Exception e) {
      throw new DataAccessException(e);
    }
    return current;
  }

	@Override
	public SchemaDAO getSchemaDAO() {
		return new SchemaJdbcDAO(getConnection());
	}

	@Override
	public TableDAO getTableDAO() {
		return new TableJdbcDAO(getConnection());
	}

	@Override
	public ColumnDAO getColumnDAO() {
		return new ColumnJdbcDAO(getConnection());
	}

	@Override
	public RelationshipDAO getRelationshipDAO() {
		return new RelationshipJdbcDAO(getConnection());
	}

}
